/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yourauthor.workcomparator;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import yourauthor.utils.ExclusionWordFilter;
import yourauthor.utils.WordMapComparator;

/**
 *
 * @author ross
 */
public class CompareByMostCommonWords implements WorkComparator {
    
    InputStream work1;
    InputStream work2;
    
    public CompareByMostCommonWords(InputStream work1, InputStream work2) {
        this.work1 = work1;
        this.work2 = work2;
    }
    
    public boolean compareWorks() throws FileNotFoundException {
        TreeMap<String, Integer> wordsForWork1 = getSortedWordCountForWork(work1);
        TreeMap<String, Integer> wordsForWork2 = getSortedWordCountForWork(work2);
        //Impossible for them to be comparable if they don't have more than 5 common words
        if ( wordsForWork2.keySet().size() < 5 || wordsForWork1.keySet().size() < 5 )
            return false;
        List<String> topTenWordsWork1 = new ArrayList<String>();
        for ( int i = 0; i < 10 && i < wordsForWork1.keySet().size(); i++ ) {
            topTenWordsWork1.add((String)wordsForWork1.keySet().toArray()[i]);
        }
        int sameWords = 0;
        for ( int i = 0; i < 10 && i < wordsForWork2.keySet().size(); i++ ) {
            if ( topTenWordsWork1.contains((String)wordsForWork2.keySet().toArray()[i])) {
                sameWords++;
            }
        }
        return sameWords >= 5;
    }

    private TreeMap<String, Integer> getSortedWordCountForWork(InputStream workInputStream) throws FileNotFoundException {
        Map<String, Integer> wordMap = new HashMap<String, Integer>();
        byte[] b = new byte[1024];
        int read = 0;
        String textBuffer = "";
        try {
            while ( (read = workInputStream.read(b)) != -1 ) {
                byte[] bytesToAdd = Arrays.copyOfRange(b, 0, read);
                textBuffer += new String(bytesToAdd);
                String leftOver = parseWordsFromStringBuffer(textBuffer, wordMap);
                textBuffer = leftOver;
            }
        } catch (IOException ex) {
            Logger.getLogger(CompareByMostCommonWords.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        //Check if any words are leftover from buffer
        parseWordsFromStringBuffer(textBuffer, wordMap);
        
        WordMapComparator wmc = new WordMapComparator(wordMap);
        TreeMap<String, Integer> sortedTreeMap = new TreeMap<String, Integer>(wmc);
        sortedTreeMap.putAll(wordMap);
        return sortedTreeMap;
    }

    private String parseWordsFromStringBuffer(String textBuffer, Map<String, Integer> wordMap) {
        if ( textBuffer == null )
            return null;
        String[] split = textBuffer.split("[\t\n .?,]");
        for ( int i = 0; i < split.length-1; i++ ) {
            if ( ExclusionWordFilter.checkAgainstExclusionList(split[i]) ) 
                continue;
            String wordToAdd = split[i];
            int currentCountForWord = 0;
            if ( wordMap.containsKey(wordToAdd.toLowerCase()) ) {
                currentCountForWord = wordMap.get(wordToAdd.toLowerCase());
            }
            currentCountForWord++;
            wordMap.put(wordToAdd.toLowerCase(),currentCountForWord);
        }
        if ( split.length > 1 )
            return split[split.length-1];
        else
            return null;
    }
    
}
